#include "include/cxxstd.h"
#include "include/lib.h"
#include "include/zero.h"
#include "corba.test.h"

using namespace zero;

namespace zerotest
{
TestResult* tr;
POA* poa;
ORB* orb;

static MessageTypeInfo tiMessage;

class ServerPOA : public ServerObject, virtual public HelloWorld
{
	void invoke(StaticServerRequest& ssr) {
		if (bstrcmp(ssr.getOpName(), sizeof("hello"), "hello")) {
			long result; Message a; char b;
			StaticAny p1(&tiMessage, StaticAny::ARGUMENT_INOUT, &a),
					  p2(&tiChar, StaticAny::ARGUMENT_IN, &b),
					  res(&tiLong, StaticAny::RESULT, &result);
			ssr.setResult(&res);
			ssr << p1 << p2;
			poa->dealWithArgs(ssr);
			try {
				result = hello(a, b);
			} catch (SessionException& ex) {
				StaticAny e(&ex, StaticAny::EXCEPTION, NULL);
				ssr.setException(&e);
				poa->writeException(ssr, 1);
				return;
			} catch (WorldException& ex) {
				StaticAny e(&ex, StaticAny::EXCEPTION, NULL);
				ssr.setException(&e);
				poa->writeException(ssr, 2);
				return;
			}
			poa->writeResults(ssr);
		}
	}
};

class MyWorld : public ServerPOA
{
	virtual long hello(Message& p1, char p2) throw (SessionException, WorldException) {
		tr->serverCallTrace = 1;

		if (p2 == 0xe) {
			tr->serverExInput = 0xe1;
			throw WorldException(0xe1);
		}

		tr->serverInput <<= sizeof(p1.c) * 8;
		tr->serverInput += p1.c;
		tr->serverInput <<= sizeof(p1.s) * 8;
		tr->serverInput += p1.s;
		tr->serverInput <<= sizeof(p2) * 8;
		tr->serverInput += p2;

		long ret = 0xa;
		p1.c = 0xb;
		p1.s = (0xc << 8) + 0xd;

		tr->serverOutput <<= sizeof(ret) * 8;
		tr->serverOutput += ret;
		tr->serverOutput <<= sizeof(p1.c) * 8;
		tr->serverOutput += p1.c;
		tr->serverOutput <<= sizeof(p1.s) * 8;
		tr->serverOutput += p1.s;
		return ret;
	}
} so;

class MyElf : public Object, virtual public ELF
{
	public:
		virtual void run(ORB* orb) {
			zerotest::orb = orb;
			tr->serverCallTrace = 1;
			poa = orb->allocPOA();
			poa->publish(typeid(HelloWorld).name(), (ServerObject*) &so, (HelloWorld*) &so);
		}
} elf;

extern "C" ELF* fix_entry(TestResult* p)
{
	tr = p;
	return &elf;
}
}

// vim: foldmarker=<([{,}])> foldmethod=marker
